package com.bolt.common.utils;

import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.Date;
import java.util.UUID;

/**
 * Created by Administrator on 2018/3/14.
 */
public class UidUtil {

    // 纳秒id的ip截取位数
    private static final int NANOTIME_IP_SUBSIZE = 3;

    /**
     * 安全服务器ID
     */
    private static String secureServerId = getLastIp(NANOTIME_IP_SUBSIZE);

    public static String UID() {
        return UUID.randomUUID().toString().toUpperCase();
    }

    public static String shortUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * @param workerId
     * @return
     * @todo 获取22位有序安全ID, 格式:13位当前毫秒+6位纳秒+3位主机ID 目前情况下任何一次提取纳秒时间都不会一样
     */
    public static BigDecimal getShortNanoTimeId(String workerId) {
        // 13位当前时间(毫秒)
        String nowTime = StrUtil.padEnd("" + System.currentTimeMillis(), 13, '0');
        // 6位纳秒间隔
        String nanoTime = "" + System.nanoTime();
        nanoTime = nanoTime.substring(nanoTime.length() - 6);
        // 3位主机ID
        String serverId = (workerId == null) ? secureServerId : workerId;
        String id = nowTime.concat(nanoTime).concat(serverId);
        return new BigDecimal(id);
    }

    /**
     * @param workerId
     * @return
     * @todo 获取26位有序安全ID, 格式:15位:yyMMddHHmmssSSS+后6位纳秒+2位(线程Id+随机数)+3位主机ID
     */
    public static BigDecimal getNanoTimeId(String workerId) {
        // 当前时间(毫秒)
        String nowTime = DateUtil.formatDate(new Date(), "yyMMddHHmmssSSS");
        // 后6位纳秒间隔
        String nanoTime = "" + System.nanoTime();
        nanoTime = nanoTime.substring(nanoTime.length() - 6);
        // 1位随机数(防范性措施)
        String randomNum = Long.toString(Math.abs(new SecureRandom().nextLong()) % 10);
        // 线程ID(实际线程ID+1位随机数)
        String threadId = Thread.currentThread().getId() + randomNum;
        // 保留2位
        threadId = threadId.substring(threadId.length() - 2);
        // 3位主机ID,根据IP提取,默认提取IPv4的后3位
        String serverId = (workerId == null) ? secureServerId : workerId;
        return new BigDecimal(nowTime.concat(nanoTime).concat(threadId).concat(serverId));
    }

    private static String getLastIp(int size) {
        String ipLastNumStr = NetUtil.getLocalhostStr();
        if (ipLastNumStr.indexOf("%") != -1) {
            ipLastNumStr = ipLastNumStr.substring(0, ipLastNumStr.indexOf("%"));
        }
        // 替换IP地址中的非数字字符
        ipLastNumStr = ipLastNumStr.replaceAll("\\.", "").replaceAll("\\:", "");
        // 保留4位
        if (ipLastNumStr.length() > size) {
            ipLastNumStr = ipLastNumStr.substring(ipLastNumStr.length() - size);
        }
        return StrUtil.padEnd(ipLastNumStr, size, '0');
    }

}
